package com.nowcoder.service;

import com.nowcoder.dao.DiscussPostMapper;
import com.nowcoder.dao.UserMapper;
import com.nowcoder.entity.DiscussPost;
import com.nowcoder.entity.User;
import com.nowcoder.util.CommunityUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.Date;

/**
 * @author by lvshh
 * @version 1.0
 * @date 2020/4/26 21:25
 */
@Service
public class AlphaService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AlphaService.class);
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DiscussPostMapper discussPostMapper;

    @Autowired
    private TransactionTemplate transactiont;

    /*
        REQUIRED:支持当前事务(外部事务)，A调B，A就是外部事务，如果A有事务就按A事务来，如果没有就创建新事务，按B的事务来
        REQUIRES_NEW：创建一个新事物，并且暂停当前事务（外部事务）
        NESTED：如果当前存在事务，外部事务，则嵌套在该事务中执行，否则就和REQUIRED一样
     */
    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    public Object save1(){
        //新增用户
        User user = new User();
        user.setUsername("alpha");
        user.setSalt("alpha");
        user.setSalt(CommunityUtil.generateUUID().substring(0,5));
        user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
        user.setEmail("alpha@qq.com");
        user.setHeaderUrl("http://images.nowcoder.com/head/149t.png");
        user.setCreateTime(new Date());
        userMapper.insertUser(user);
        //新增帖子
        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle("hello");
        post.setContent("新人报道");
        post.setCreateTime(new Date());
        discussPostMapper.insertDiscussPost(post);

        Integer.valueOf("abc");
        return "ok";
    }

    public Object save2(){
        transactiont.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        transactiont.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);

        return transactiont.execute(new TransactionCallback<Object>() {

            @Nullable
            @Override
            public Object doInTransaction(TransactionStatus transactionStatus) {
                User user = new User();
                user.setUsername("beta");
                user.setSalt("alpha");
                user.setSalt(CommunityUtil.generateUUID().substring(0,5));
                user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
                user.setEmail("beta@qq.com");
                user.setHeaderUrl("http://images.nowcoder.com/head/999t.png");
                user.setCreateTime(new Date());
                userMapper.insertUser(user);
                //新增帖子
                DiscussPost post = new DiscussPost();
                post.setUserId(user.getId());
                post.setTitle("你好");
                post.setContent("我是新人");
                post.setCreateTime(new Date());
                discussPostMapper.insertDiscussPost(post);

                Integer.valueOf("abc");
                return "ok";

            }
        });
    }

    //让该方法在多线程的环境下被异步的调用
    @Async
    public void executor1(){
        LOGGER.debug("executor1");
    }

    @Scheduled(initialDelay = 10000,fixedRate = 1000)
    public void executor2(){
        LOGGER.debug("executor2");
    }
}
